<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Pango in GTK#</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, GTK#, Pango, C#, programming, Linux">
<meta name="description" content="In this part of the GTK# tutorial, we present
the Pango library.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Pango</h1>

<p>
In this part of the GTK# programming tutorial, we will explore the Pango library.
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
Pango is a free and open source computing library for rendering internationalized 
texts in high quality. Different font backends can be used, allowing cross-platform support.
(wikipedia)
</p>

<p>
Pango provides advanced font and text handling that is used for Gdk and Gtk. 
</p>

<h2>Simple example</h2>

<p>
In our first example, we show, how to change font for our label widget.   
</p>

<div class="codehead">quotes.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    private Label label;

    public SharpApp() : base("Pango")
    {
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        string text = @"Excess of joy is harder to bear than any amount of sorrow.
The more one judges, the less one loves.
There is no such thing as a great talent without great will power. ";
       
        label = new Label(text);

        Pango.FontDescription fontdesc = Pango.FontDescription.FromString("Purisa 10");
        label.ModifyFont(fontdesc);

        Fixed fix = new Fixed();

        fix.Put(label, 5, 5);
        Add(fix);
        ShowAll();
    }


    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
In the above code example, we have a label widget with three quotations. 
We change it's font to Purisa 10.
</p>

<pre class="explanation">
string text = @"Excess of joy is harder to bear than any amount of sorrow.
...
</pre>

<p>
This is the text to show in the label.
</p>

<pre class="explanation">
Pango.FontDescription fontdesc = Pango.FontDescription.FromString("Purisa 10");
</pre>

<p>
The <code>FontDescription</code> is used to specify the characteristics of a font to load.
The <code>FromString()</code> method creates a new font description from a string representation.
</p>

<pre class="explanation">
label.ModifyFont(fontdesc);
</pre>

<p>
We change the font of the label widget to Purisa 10.
</p>

<img src="/img/gui/sharpgtk/quotations.png" alt="Quotations">
<div class="figure">Figure: Quotations</div>


<h2>System fonts</h2>

<p>
The next code example shows all available fonts in a <code>TreeView</code> widget. 
</p>

<div class="codehead">systemfonts.cs</div> 
<pre class="code">
using System;
using Pango;
using Gtk;


public class SharpApp : Window
{
    ListStore store;
    FontFamily[] fam;

    public SharpApp() : base("System fonts")
    {
        BorderWidth = 8;

        SetDefaultSize(350, 250);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };


        ScrolledWindow sw = new ScrolledWindow();
        sw.ShadowType = ShadowType.EtchedIn;
        sw.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);

        Context context = this.CreatePangoContext();
        fam = context.Families;

        store = CreateModel();

        TreeView treeView = new TreeView(store);
        treeView.RulesHint = true;
        sw.Add(treeView);

        CreateColumn(treeView);

        Add(sw);
        ShowAll();
    }

    void CreateColumn(TreeView treeView)
    {
        CellRendererText rendererText = new CellRendererText();
        TreeViewColumn column = new TreeViewColumn("FontName",
            rendererText, "text", Column.FontName);
        column.SortColumnId = (int) Column.FontName;
        treeView.AppendColumn(column);
    }


    ListStore CreateModel()
    {
        ListStore store = new ListStore( typeof(string) );

        foreach (FontFamily ff in fam) {
            store.AppendValues(ff.Name);
        }

        return store;
    }

    enum Column
    {
        FontName
    }

  
    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
The code example shows all available fonts on a system.
</p>

<pre class="explanation">
Context context = this.CreatePangoContext();
</pre>

<p>
This code line creates a <code>Pango.Context</code> object. 
It contains global information about the rendering process of text. 
</p>

<pre class="explanation">
fam = context.Families;
</pre>

<p>
From the context object, we retrieve all available font families. 
</p>

<pre class="explanation">
foreach (FontFamily ff in fam) {
    store.AppendValues(ff.Name);
}
</pre>

<p>
During the model creation of the <code>TreeView</code> widget, 
we get all font names from the array of font families and put them 
into the list store. 
</p>

<img src="/img/gui/sharpgtk/systemfonts.png" alt="System fonts">
<div class="figure">Figure: System fonts</div>


<h2>Unicode</h2>

<p>
Pango is used to work with internationalized text. 
</p>

<div class="codehead">unicode.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {


    public SharpApp() : base("Unicode")
    {
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        string text = @"Фёдор Михайлович Достоевский родился 30 октября (11 ноября)
1821 года в Москве.Был вторым из 7 детей. Отец, Михаил Андреевич, работал в 
госпитале для бедных. Мать, Мария Фёдоровна (в девичестве Нечаева),
происходила из купеческого рода.";
       
        Label label = new Label(text);

        Pango.FontDescription fontdesc = Pango.FontDescription.FromString("Purisa 10");
        label.ModifyFont(fontdesc);

        Fixed fix = new Fixed();

        fix.Put(label, 5, 5);
        Add(fix);
        ShowAll();
    }


    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
We show some text in azbuka. 
</p>

<pre class="explanation">
string text = @"Фёдор Михайлович Достоевский родился 30 октября ...
</pre>

<p>
We can directly use the unicode text. 
</p>

<pre class="explanation">
Label label = new Label(text);
</pre>

<p>
We normally use it in the label widget. 
</p>

<img src="/img/gui/sharpgtk/unicode.png" alt="Unicode">
<div class="figure">Figure: Unicode</div>



<h2>Coloured text</h2>

<p>
In the final example, we will further explore Pango capabilities. 
We will draw a centered, coloured text on a <code>DrawingArea</code>
widget.
</p>

<div class="codehead">coloured.cs</div>
<pre class="code">
using System;
using Gtk;
using Pango;


public class SharpApp : Window
{

    public SharpApp () : base ("Australia")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };

        Gdk.Color white = new Gdk.Color(255, 255, 255);

        DrawingArea drawingArea = new DrawingArea();
        drawingArea.ModifyBg(StateType.Normal, white);
        drawingArea.ExposeEvent += OnExposeEvent;

        Add(drawingArea);

        ShowAll();
    }

    void OnExposeEvent (object sender, ExposeEventArgs a)
    {
        DrawingArea drawingArea = sender as DrawingArea;

        int width = drawingArea.Allocation.Width;

        Gdk.PangoRenderer renderer = Gdk.PangoRenderer.GetDefault(drawingArea.Screen);
        renderer.Drawable = drawingArea.GdkWindow;
        renderer.Gc = drawingArea.Style.BlackGC;
        
        Context context = drawingArea.CreatePangoContext();
        Pango.Layout layout = new Pango.Layout(context);
        
        layout.Width = Pango.Units.FromPixels(width);
        layout.SetText("Australia");
        
        FontDescription desc = FontDescription.FromString("Serif Bold 20");
        layout.FontDescription = desc;

        renderer.SetOverrideColor(RenderPart.Foreground, new Gdk.Color(200, 30, 30));
        layout.Alignment = Pango.Alignment.Center;
        renderer.DrawLayout(layout, 0, 0);
        
        renderer.SetOverrideColor(RenderPart.Foreground, Gdk.Color.Zero);
        renderer.Drawable = null;
        renderer.Gc = null;
    }
    
    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
We draw "Australia" text, horizontally centered, coloured in dark red colour. 
</p>

<pre class="explanation">
Gdk.PangoRenderer renderer = Gdk.PangoRenderer.GetDefault(drawingArea.Screen);
renderer.Drawable = drawingArea.GdkWindow;
renderer.Gc = drawingArea.Style.BlackGC;
</pre>

<p>
We get the default renderer for the screen, and set it up for drawing.
</p>

<pre class="explanation">
Context context = drawingArea.CreatePangoContext();
Pango.Layout layout = new Pango.Layout(context);
</pre>

<p>
We create a <code>Pango.Layout</code>. It is a high level driver for
laying out entire blocks of text.
</p>

<pre class="explanation">
layout.Width = Pango.Units.FromPixels(width);
</pre>

<p>
We specify the layouts width. 
</p>

<pre class="explanation">
layout.SetText("Australia");
</pre>

<p>
We set our text.
</p>

<pre class="explanation">
FontDescription desc = FontDescription.FromString("Serif Bold 20");
layout.FontDescription = desc;
</pre>

<p>
We specify a font for our layout.
</p>


<pre class="explanation">
renderer.SetOverrideColor(RenderPart.Foreground, new Gdk.Color(200, 30, 30));
layout.Alignment = Pango.Alignment.Center;
</pre>

<p>
We set a color and alignment. 
</p>

<pre class="explanation">
renderer.DrawLayout(layout, 0, 0);
</pre>

<p>
We draw the Pango layout. 
</p>


<pre class="explanation">
renderer.SetOverrideColor(RenderPart.Foreground, Gdk.Color.Zero);
renderer.Drawable = null;
renderer.Gc = null;
</pre>

<p>
We clean up resources. 
</p>

<img src="/img/gui/sharpgtk/australia.png" alt="Australia">
<div class="figure">Figure: Australia</div>

<p>
In this chapter of the GTK# programming library, we worked with Pango library.
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br>

<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified January 24, 2009  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
